#include "command.h"
#include "metaFile.h"
#define PATHSTACK_MAXSIZE 1024
#define FILENAME_MAXLEN 65

// 这个路径栈只用来处理掉客户端传入路径中的../.
typedef struct pathStack_s{
    char* pathArr[PATHSTACK_MAXSIZE];
    int top;// 栈顶指针，为-1时表示为空
}pathStack_t;
// 初始化一个用来保存路径的栈
int pathStackInit(pathStack_t* pathStack);
// 出栈成功返回0，失败返回-1
int popStack(pathStack_t* pathStack);
// 压栈成功返回0，失败返回-1
int pushStack(pathStack_t* pathStack,const char * str);
//销毁栈，正常销毁返回0，销毁失败返回-1
int destroyStack(pathStack_t *pathStack);
// 获取路径
int getPath(const pathStack_t* pathStack,char* result);

// 保证返回的是一个完整的路径 /dir1/dir2/.././dir3 --->/dir1/dir3  dir3 --->dir
// 正确处理返回0，发生错误返回-1
int getFormattedPath (MYSQL *mysql,char*srcPath,char* destPath,int pathId,char* destFileName);

// 初始化一个用来保存路径的栈
int pathStackInit(pathStack_t* pathStack){
    bzero(pathStack,sizeof(pathStack_t));
    pathStack->top=-1;
    /* pathStack->rootPathPointer=-1;// 只在curPathInit中初始化一次 */
    return 0;
}
// 出栈成功返回0，失败返回-1
int popStack(pathStack_t* pathStack){
    if(pathStack->top != -1){
        printf("pop:|%s|\n",pathStack->pathArr[pathStack->top]);
        free(pathStack->pathArr[pathStack->top]);
        --pathStack->top;
    }else{
        return -1;
    }
    return 0;
}
// 压栈成功返回0，失败返回-1
int pushStack(pathStack_t* pathStack,const char * str){
    if((pathStack->top)<(PATHSTACK_MAXSIZE-1)){
        char* pathName = (char*)calloc(strlen(str)+1,sizeof(char));
        strcpy(pathName,str);
        printf("%d push: %s\n",pathName==NULL, pathName);
        ++(pathStack->top);
        pathStack->pathArr[pathStack->top]=pathName;
    }else{
        return -1;
    }
    return 0;
}
//销毁栈，正常销毁返回0，销毁失败返回-1
int destroyStack(pathStack_t *pathStack){
    if(pathStack == NULL){
        return -1;
    }
    while(pathStack->top >= 0){
        popStack(pathStack);
    }
    pathStack->top = -1;
    return 0;
}
// 保证返回的是一个完整的路径 /dir1/dir2/.././dir3 --->/dir1/dir3  dir3 --->dir1/dir3 
// 正确处理返回0，发生错误返回-1
int getFormattedPath (MYSQL *mysql,char*srcPath,char* destPath,int pathId,char* destFileName){
    pathStack_t pathStack;
    pathStackInit(&pathStack);

    char delim[] = "/";
    char* saveptr;

    if(srcPath[0]!='/'){
        printf("-----curPath push----------\n");
        // 用pathId找到对应的路径curPath
        char curPath[1024] = {0};
        if(getPathByFid(mysql,pathId,curPath)!=0){
            printf("getFormattedPath:wrong pathId\n");
            return -1;
        }
        char* curPathToken = strtok_r(curPath,delim,&saveptr);
        while(curPathToken!=NULL){
            pushStack(&pathStack,curPathToken);
            curPathToken = strtok_r(NULL,delim,&saveptr);
        }
        //=======DEBUG==========
        char tempPrintPath[1024];
        getPath(&pathStack,tempPrintPath);
        printf("DEBUG1: tempPrintPath:|%s|\n",tempPrintPath);
        //======================
        printf("-----curPath push----------\n");
    }
    // 处理..和.的情况，并将token压栈
    char* token = strtok_r(srcPath,delim,&saveptr);
    while(token!=NULL){
        printf("DEBUG2:token=|%s|\n",token);
        if(strcmp(token,"..")==0){
            if(pathStack.top==-1){
                printf("getFormattedPath: path error (The access path is illegal)\n");
                return -1;// ../../../...太多，超出了允许访问的位置
            }
            popStack(&pathStack);
        } else if(strcmp(token,".")!=0){ //不是../也不是./
            pushStack(&pathStack,token);
        }
        token = strtok_r(NULL,delim,&saveptr);
    }
    if(destFileName!=NULL){
        destFileName[0]='\0';
        strncat(destFileName,pathStack.pathArr[pathStack.top],FILENAME_MAX);
    }
    destPath[0]='\0';
    getPath(&pathStack,destPath);
    destroyStack(&pathStack);
    return 0;
}

// 获取路径
int getPath(const pathStack_t* pathStack,char* result){
    result[0]='\0';
    if(pathStack->top==-1){
        strncat(result,"/",2);
    }
    for(int i = 0;i<=pathStack->top;++i){
        strncat(result,"/",2);
        strncat(result,pathStack->pathArr[i],FILENAME_MAXLEN);
    }
    return 0;
}

